package com.wechat.page.contact.select;

import java.util.List;

import com.swak.entity.Toggle;
import com.swak.fx.support.AbstractPage;
import com.swak.fx.support.FXMLView;
import com.swak.fx.support.ui.UI;
import com.swak.fx.support.ui.UIButton;
import com.swak.fx.support.ui.UIEvent;
import com.swak.fx.support.ui.UIScrollPane;
import com.wechat.dto.ContactDTO;
import com.wechat.page.contact.card.ContactThumbsComp;
import com.wechat.page.contact.misc.ContactThumb;

import javafx.beans.binding.Bindings;
import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener.Change;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.geometry.Insets;
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.text.Text;

/**
 * 联系人选择
 * 
 * @author lifeng
 */
@FXMLView(title = "联系人选择-主页", value = "ContactSelectMain.fxml", css = "ContactSelectMain.css", stageStyle = "TRANSPARENT")
public class ContactSelectMain extends AbstractPage {

	public static final String ToggleEvent = "Toggle.Event";
	public static final String ConfrimEvent = "Confirm.Event";

	@FXML
	private Text title;
	@FXML
	private Text tip;
	@FXML
	private UIScrollPane scroll;
	@FXML
	private UIButton confirmBtn;
	@FXML
	private UIButton cancelBtn;

	private ContactThumbsComp contacts;

	public ContactSelectMain() {
		this.contacts = this.NewComp(ContactThumbsComp.class);
	}

	@Override
	public void initializeParts() {
		super.initializeParts();
		this.confirmBtn.Success();
		this.cancelBtn.Inverse();
		this.scroll.setContent(this.contacts.getRoot());
		this.scroll.setFitToWidth(true);
		this.scroll.setHbarPolicy(ScrollBarPolicy.NEVER);
		this.scroll.setVbarPolicy(ScrollBarPolicy.AS_NEEDED);
		this.contacts.removeAbleProperty().set(true);
		this.contacts.enableChildRemoveAnimation().set(true);

		GridPane.setMargin(this.confirmBtn, new Insets(0, 10, 0, 0));
		GridPane.setMargin(this.cancelBtn, new Insets(0, 0, 0, 10));
	}

	@Override
	public void setupEventHandlers() {
		super.setupEventHandlers();
		this.contacts.getRoot().addEventHandler(UIEvent.UI, this.contactHandler);
		this.registerUIEventUseFireCloseEvent(this.cancelBtn, UI.Events.Window_Close);
		this.confirmBtn.addEventHandler(MouseEvent.MOUSE_CLICKED, (e) -> {
			this.$emit(ConfrimEvent, true);
		});
	}

	private void onContactHandler(UIEvent event) {
		event.consume();
		if (event.getCmd().equals(ContactThumb.RemoveEvent)) {
			this.$emit(ToggleEvent, new Toggle<>().setActive(false).setValue(event.getData()));
		}
	}

	@Override
	public void setupBindings() {
		super.setupBindings();
		this.contacts.contactsProperty().bind(this.changedProperty);
		this.tip.visibleProperty().bind(Bindings.createBooleanBinding(() -> {
			int size = this.changedProperty.size();
			return size > 0;
		}, this.changedProperty));
		this.tip.textProperty().bind(Bindings.createStringBinding(() -> {
			int size = this.changedProperty.size();
			return "已选择 " + size + "人";
		}, this.changedProperty));
	}

	@Override
	public void setupValueChangedListeners() {
		super.setupValueChangedListeners();
		this.contactsProperty.addListener(this::onContactsChange);
	}

	@SuppressWarnings("unchecked")
	private void onContactsChange(Change<? extends Toggle<ContactDTO>> c) {
		while (c.next()) {
			if (c.wasReplaced()) {
				List<Toggle<ContactDTO>> adds = (List<Toggle<ContactDTO>>) c.getAddedSubList();
				for (Toggle<ContactDTO> contact : adds) {
					if (contact.isActive()) {
						this.changedProperty.add(contact.getValue());
					} else {
						this.changedProperty.remove(contact.getValue());
					}
				}
			} else if (c.wasAdded()) {
				List<Toggle<ContactDTO>> adds = (List<Toggle<ContactDTO>>) c.getAddedSubList();
				for (Toggle<ContactDTO> contact : adds) {
					if (contact.isActive()) {
						this.changedProperty.add(contact.getValue());
					}
				}
			} else if (c.wasRemoved()) {
				List<Toggle<ContactDTO>> adds = (List<Toggle<ContactDTO>>) c.getRemoved();
				for (Toggle<ContactDTO> contact : adds) {
					this.changedProperty.remove(contact.getValue());
				}
			}
		}
	}

	// ================================================================================
	// Properties
	// ================================================================================
	private final ListProperty<ContactDTO> changedProperty = new SimpleListProperty<>(
			FXCollections.observableArrayList());
	private final ListProperty<Toggle<ContactDTO>> contactsProperty = new SimpleListProperty<>(
			FXCollections.observableArrayList());

	public ListProperty<Toggle<ContactDTO>> contactsProperty() {
		return contactsProperty;
	}

	// ================================================================================
	// 事件监听
	// ================================================================================

	private EventHandler<UIEvent> contactHandler = (e) -> this.onContactHandler(e);
}
